package com.gitee.fastmybatis.core.ext;

import com.gitee.fastmybatis.core.ext.info.TableInfo;
import com.gitee.fastmybatis.core.util.ClassUtil;
import org.apache.ibatis.session.SqlSessionFactory;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

/**
 * @author tanghc
 */
public class ExtContext {

	// key: entityClassName, value: mapperClass
	private static final Map<String, Class<?>> entityMapper = new HashMap<>(16);

	// key：mapperClassName, value: entityClass
	private static final Map<String, Class<?>> mapperEntity = new HashMap<>(16);


	private static final Map<String, SqlSessionFactory> sqlSessionFactoryMapForMapper = new HashMap<>();

	private static Map<Class<?>, TableInfo> tableInfoMap = new HashMap<>();

	public static void addMapperClass(Collection<Class<?>> mapperClasses) {
		for (Class<?> mapperClass : mapperClasses) {
			Class<?> entityClass = getEntityClass(mapperClass);
			entityMapper.put(entityClass.getName(), mapperClass);
			mapperEntity.put(mapperClass.getName(), entityClass);
		}
	}

	public static Class<?> getMapperClassByEntityClass(Class<?> entityClass) {
		return entityMapper.get(entityClass.getName());
	}

	public static Class<?> getEntityClassByMapperClass(Class<?> mapperClass) {
		mapperClass = ClassUtil.getRealMapperClass(mapperClass);
		return mapperEntity.get(mapperClass.getName());
	}
	
	private static Class<?> getEntityClass(Class<?> mapperClass) {
		String name = mapperClass.getName();
		if (mapperClass.isInterface() || name.startsWith(ClassUtil.PROXY_PREFIX)) {
			return ClassUtil.getSuperInterfaceGenericType(mapperClass, 0);
		} else {
			return ClassUtil.getSuperClassGenericType(mapperClass, 0);
		}
	}

	public static void addSqlSessionFactory(Class<?> mapperClass, SqlSessionFactory sqlSessionFactory) {
		sqlSessionFactoryMapForMapper.put(mapperClass.getName(), sqlSessionFactory);
	}

	public static SqlSessionFactory getSqlSessionFactoryByMapperClass(Class<?> mapperClass) {
		return sqlSessionFactoryMapForMapper.get(mapperClass.getName());
	}

	public static void addTableInfo(Class<?> mapperClass, TableInfo tableInfo) {
		tableInfoMap.put(mapperClass, tableInfo);
	}

	public static TableInfo getTableInfo(Class<?> mapperClass) {
		return tableInfoMap.get(mapperClass);
	}

	public static void clearTableInfo() {
		tableInfoMap.clear();
		tableInfoMap = null;
	}
}
